/**
 * 
 */
package la.ge.server.servlets.gs2ge;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import la.common.CommonException;
import la.common.xml.Node2String;
import la.ge.kml.ErrorReportKMLBuilder;
import la.ge.kml.KMLConstants;
import la.ge.server.GeServerContext;
import la.ge.server.gs2ge.GSResultRecs2BigNode;
import la.ge.server.gs2ge.GSResultRecs2BigNode.GenParam;
import la.ge.server.servlets.gs2ge.util.Util;
import la.gs.GSDocParseResult;
import la.gs.GSExtractor;
import la.gs.GSearchCriteria;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;

/**
 * Google search result viewer 
 * @author labile
 *
 */
@SuppressWarnings("serial")
public class GetBigNodeGSResultServlet extends HttpServlet
{
	private Log logger = LogFactory.getLog( this.getClass() );
	private GeServerContext geServerContext;

	
	
	@Override
	public void init(ServletConfig arg0) throws ServletException {
		super.init(arg0);
    	geServerContext = (GeServerContext) this.getServletContext().getAttribute( GeServerContext.ATTRIB_NAME );
	}

	/**
	 * http url parameter:
	 * {@link GSearchCriteria} fields(optional, null for use setting)
	 * int firstGSResultIndex(optional, null for 0)
	 */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
    	Util.trySetURLQueryCharset( request );
    	
		GSearchCriteria searchCriteria = Util.extractSearchCriteria(request);
    	if( searchCriteria.getKeyword() == null ) {//invalid searchCriteria
    		synchronized (geServerContext.getGsSetting()) {
        		searchCriteria = geServerContext.getGsSetting().searchCriteria;
			}
    	}
    	
		response.setContentType( KMLConstants.KML_MIME );
		response.setCharacterEncoding( "utf-8" );
		response.setStatus(HttpServletResponse.SC_OK);
		
    	if( searchCriteria == null ) {// no default setting & no instant parameter
    		ErrorReportKMLBuilder errorReportKMLBuilder = new ErrorReportKMLBuilder();
    		response.getWriter().print( errorReportKMLBuilder.build( "no default setting & no instant parameter" ) );
    		return;
    	}
    	
   	  	int firstGSResultIndex = 0;
   	  	try {
   	  		firstGSResultIndex = Integer.parseInt( request.getParameter( "firstGSResultIndex" ) );
   	  	}catch(Exception e) {/*use default value*/}

		try {
			response.getWriter().println(gen( searchCriteria, firstGSResultIndex, request ));
		} catch ( CommonException e ) {
    		ErrorReportKMLBuilder errorReportKMLBuilder = new ErrorReportKMLBuilder();
    		response.getWriter().print( errorReportKMLBuilder.build( e ) );
		}
    }
    
 	public String gen(GSearchCriteria searchCriteria, int firstGSResultIndex,
 			HttpServletRequest request) throws CommonException {
		GSExtractor extractor = new GSExtractor();
		GSDocParseResult docParseResult = extractor.extractFromGoogle( searchCriteria, firstGSResultIndex, 10 );
		
		logger.debug( docParseResult );
		
		int totalGSResultQty = 0;
		if( docParseResult.getTotalRecordQty() == null || docParseResult.getTotalRecordQty() < 0 ) {//cann't get total record qty
			totalGSResultQty = firstGSResultIndex + docParseResult.getRecords().size();
		} else {
			totalGSResultQty = docParseResult.getTotalRecordQty();
		}
		
		GSResultRecs2BigNode resultRecs2BigNode = new GSResultRecs2BigNode();

		/**
		 * fileType=X&keyword=X&firstGSResultIndex=X
		 */
		final String searchURLQueryParam = Util.encodeSearchCriteria2URLQuery( searchCriteria )
		+ "&firstGSResultIndex=";
		
		// far result set href link:
		// /servlets/-
		// la.ge.server.servlets.gs2ge.GetBigNodeGSResultServlet?fileType=X&keyword=X&firstGSResultIndex=X
		final String farResultSetLoopLinkURL = 
			Util.genClientAccessURLPrefix( request ) +
			geServerContext.getServletPath( this.getClass() ) + "?"
			+ searchURLQueryParam;

		/**
		 * /servlets/la.ge.server.servlets.gs2ge.GetPlainGSResultServlet?fileType=X&keyword=X&firstGSResultIndex=X
		 */
		final String nearResultSetLoopLinkURL = 
			Util.genClientAccessURLPrefix( request ) +
			geServerContext.getServletPath( GetPlainGSResultServlet.class ) + "?"
			+ searchURLQueryParam;
		
		Document doc = resultRecs2BigNode.act(
				docParseResult.getRecords(),
				firstGSResultIndex,
				totalGSResultQty, 
				new GenParam(){
					public String genFarResultSetHref(int firstGSResultIndex) {
						return Util.URLQueryEncode( farResultSetLoopLinkURL + firstGSResultIndex );
					}

					public String genNearResultSetHref(int firstGSResultIndex) {
						return Util.URLQueryEncode( nearResultSetLoopLinkURL + firstGSResultIndex );
					}} );

		String result = Node2String.node2String( doc );
		logger.debug(result);
		return result;
	}
}